﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Common;
using Common.Views;

namespace BL_WServices
{
    /// <summary>
    /// This is the Implementation of ProductsService which is bound by a ServiceContract
    /// </summary>
    [ServiceContract]
    public interface IProductsService
    {
        /// <summary>
        /// Get all the Products from the database
        /// </summary>
        /// <returns>Returns all the Products within the Products Entity.</returns>
        [OperationContract]
        IQueryable<Product> GetAllProducts();

        /// <summary>
        /// Gets all the comments for a particular product
        /// </summary>
        /// <param name="productID">Used to get comments for a particular product</param>
        /// <returns>Returns a list of comments by productID</returns>
        [OperationContract]
        IQueryable<ProductComment> GetCommentsByProductID(int productID);

        /// <summary>
        /// Get all the products from the database through the productID
        /// </summary>
        /// <param name="productID">Of type int. The product is returned from the database 
        /// through the productID.</param>
        /// <returns>Returns the Product by its ID</returns>
        [OperationContract]
        Product GetProductById(int productID);

        /// <summary>
        /// Add Products to Cart Entity using the Username, Product ID and Quantity
        /// </summary>
        /// <param name="username">Username of the customer who added products to cart</param>
        /// <param name="productId">ProductID of the product added to cart</param>
        /// <param name="qty">Quantity number of ProductID added to cart</param>
        [OperationContract]
        string AddToCart(string username, int productId, int qty);

        /// <summary>
        /// Add comment to a particular product
        /// </summary>
        /// <param name="username">Of type string. Username who entered the comment</param>
        /// <param name="productID">Of type int. ProductID that has a new comment associated to it</param>
        /// <param name="comment">Of type string. The actual comment</param>
        [OperationContract]
        void AddComment(string username, int productID, string comment);
        
        /// <summary>
        /// Return the products from the Cart Entity depending on the username
        /// </summary>
        /// <param name="username">Used to get the products from the cart entity depending on the username</param>
        /// <returns></returns>
        [OperationContract]
        IQueryable<CartView> GetProductsFromCart(string username);

        /// <summary>
        /// Returns the average rating of a product
        /// </summary>
        /// <param name="productID">Of type int. Used to get the the average rating for that product</param>
        /// <returns>Returns IQueryable int - Returns the average rating of a product</returns>
        [OperationContract]
        IQueryable<int> ReturnAverageRating(int productID);

        /// <summary>
        /// Add rating by username, productID and the rating number
        /// </summary>
        /// <param name="username">Of type string. The username that will add the rating</param>
        /// <param name="productId">Of type int. The productID that will have the rating</param>
        /// <param name="rating">Of type int. The number that will be added to rate the product</param>
        /// <returns>Returns a string message rated if already rated</returns>
        [OperationContract]
        string AddProductRating(string username, int productId, int rating);

        /// <summary>
        /// Return the product details of a product
        /// </summary>
        /// <param name="productID">Of type int. Used to get the product details from the database</param>
        /// <param name="orderID">Of type Guid. Used to get the product details from the database by orderID</param>
        /// <returns>Returns the product details from the database depending on the productID </returns>
        [OperationContract]
        OrdersView GetProductDetails(int productID, Guid orderID);

        /// <summary>
        /// Get all the Categories from the Table Categories
        /// </summary>
        /// <returns>Returns a list of categories</returns>
        [OperationContract]
        IEnumerable<Category> GetCategories();

        /// <summary>
        /// Return a list of products depending on their categoryID
        /// </summary>
        /// <param name="categoryID">Of type int. Used to get a list of products depending on the categoryID</param>
        /// <returns>Returns a list of products</returns>
        [OperationContract]
        IQueryable<Product> GetProductsByCategoryRefinement(int categoryID);

        /// <summary>
        /// Returns a list of products depending on their product name
        /// </summary>
        /// <param name="keyword">Of type string. Used to return a list of products depending on the name</param>
        /// <returns>Returns a list of products</returns>
        [OperationContract]
        IEnumerable<Product> SearchProductByName(string keyword);

        /// <summary>
        /// Returns a list of products depending on the price
        /// </summary>
        /// <param name="minPrice">Of type decimal. </param>
        /// <param name="maxPrice">Of type decimal. </param>
        /// <returns>Returns a list of products depending on the minimum Price and maximum Price</returns>
        [OperationContract]
        IEnumerable<Product> SearchProductByPrice(decimal minPrice, decimal maxPrice);

        /// <summary>
        /// Returns a list of products in ascending order
        /// </summary>
        /// <returns>Returns a list of products in ascending order, ordered by the price</returns>
        [OperationContract]
        IEnumerable<Product> SearchProductByPriceASC();

        /// <summary>
        /// Returns a list of products in descending order
        /// </summary>
        /// <returns>Returns a list of products in descending order, ordered by the price</returns>
        [OperationContract]
        IEnumerable<Product> SearchProductByPriceDESC();

        /// <summary>
        /// Returns a list of products in descending order
        /// </summary>
        /// <returns>Returns a list of products in descending order, ordered by the date</returns>
        [OperationContract]
        IEnumerable<Product> SearchProductByDateASC();

        /// <summary>
        /// Returns a list of products by username
        /// </summary>
        /// <param name="username">Of type string. Used to get the products by username</param>
        /// <returns></returns>
        [OperationContract]
        IQueryable<CartView> GetAllProductsByUsername(string username);
    }
}
